<?php
/**
 * Created by PhpStorm.
 * User: 牛赞赞
 * Date: 2020/12/30
 * Time: 16:20
 */

namespace App\Game\Logic;


use App\Game\Conf\GameProgress;
use App\Game\Conf\MainCmd;
use App\Game\Conf\SubCmd;
use App\Game\Core\AStrategy;
use App\Game\Core\Packet;
use App\Model\User;

class GamePull extends AStrategy
{
    /**
     * 将用户拉进正在进行游戏
     */
    public function exec()
    {
        $room_no = isset($this->_params['data']['room_no']) ? $this->_params['data']['room_no'] : null;
        $account = $this->_params['userinfo']['account'];
        $game_conf = $this->game_conf;
        $user_conf = $this->user_conf;
        $serv = server();
        if (empty($room_no)) {
            $msg = ['status' => 1, 'info' => '房间号参数缺失'];
            $this->errResp($msg);
            pushForceQuitMsg($room_no, $account);
            return;
        }

        // 游戏数据
        $user_room_data_key = sprintf($game_conf['user_room_data'], $room_no);
        // 获取资源成功
        $room_data_hash = redis()->hGetAll($user_room_data_key);//取出房间数据
        if (empty($room_data_hash)) {
            $msg = ['status' => 2, 'info' => '游戏已结束'];
            $this->errResp($msg);
            pushForceQuitMsg($room_no, $account);
            return;
        }


        $user_room_data = json_decode($room_data_hash[$account], true);
        //查看定时器工作状态，如果已经很久没动过，表明该房间已卡死，此时强制踢出所有用户
        $timer = json_decode($room_data_hash['timer'], true);
        $now = time();
        $gameTime = strtotime($timer['time']);
        if ($now - $gameTime > 20) {
            $msg = ['status' => '强制退出'];
            $serv = server();
            $fd = $this->_params['userinfo']['fd'];
            pushDataToUser($serv, $fd, $msg, SubCmd::FORCE_QUIT_ROOM_RESP);
            //清空房间
            clearRoomDataAll($room_no);
            return;
        }

        if (isset($room_data_hash['is_game_over']) && $room_data_hash['is_game_over'] == 1) {
            // 游戏已经结束
            $msg = ['status' => 3, 'info' => '游戏已结束'];
            $this->errResp($msg);
            pushForceQuitMsg($room_no, $account);
            return;
        }
        if (!playerStatus($room_no, $account)) {
            pushForceQuitMsg($room_no, $account);
            return;
        }

        //查看当前游戏进度
        $progress = getGameProgress($room_no);
        if (!in_array($progress, [GameProgress::GAME_OUT_CARD, GameProgress::GAME_CHANGE_CARD,
            GameProgress::GAME_CHOOSE_COLOR, GameProgress::GAME_CHECK_HPG])) {
            pushForceQuitMsg($room_no, $account);
            return;
        }

        //先设置玩家掉线状态
        playerOffline($room_no, $account);
        $chair_id = getChairIdbyAccount($room_no, $account);
        $wait_chair = ($chair_id + 1) > 4 ? ($chair_id + 1 - 4) : $chair_id + 1;
        $wait_chair_next = ($wait_chair + 1) > 4 ? ($wait_chair + 1 - 4) : $wait_chair + 1;
//        $waitArr = [$wait_chair, $wait_chair_next];
        $waitArr = [$chair_id];
        while (true) {
            $progress = getGameProgress($room_no);
            if (!in_array($progress, [GameProgress::GAME_JOIN, GameProgress::GAME_PREPARE,
                GameProgress::GAME_CACULAR])) {
                $room_data = getRoomData($room_no);

                if (in_array($progress, [GameProgress::GAME_OUT_CARD, GameProgress::GAME_CHECK_HPG])) {
                    if (in_array($room_data['next_chair_id'], $waitArr)) {
                        continue;
                    }
                }
//                // 取消托管
//                $user_room_data = json_decode($room_data[$account], true);
//                $user_room_data['take_over'] = 0;
//                updateRoomData($room_no, [$account => $user_room_data]);
                $gtype = getGameProgressType($room_no);
                $user_data['is_real'] = $gtype == 1 ? 0 : 1;
                $user_data['chair_id'] = $user_room_data['chair_id'];
                $user_data['master'] = (int)$room_data['master'];
                $user_data['take_over'] = $user_room_data['take_over'];
                $hand = json_decode($room_data['hand'], true);
                $user_data['hand_num'] = count($hand);
                $room_data = getRoomData($room_no);
                $user_data['room_data'] = $this->roomData($room_data);
                $user_data['play'] = [
                    'last_chair_id' => $room_data['last_chair_id'],
                    'next_chair_id' => $room_data['next_chair_id']
                ];
                playerOnline($room_no, $account);
                dd('掉线重连信息', $user_data);
                $fd = getFdByAccount($account);
                pushDataToUser($serv, $fd, $user_data, SubCmd::SUB_GAME_PULL_RESP);
                break;
            }

            $prepareArr = getGamePrepareALL($room_no);
            if ($prepareArr < 4) {
                pushForceQuitMsg($room_no, $account);
                clearRoomDataAll($room_no);
                break;
            }
            $offlinePlayers = [];
            foreach ($prepareArr as $acc => $status) {
                if ($status == GameProgress::USER_OFFLINE) {
                    $offlinePlayers[] = $acc;
                }
            }
            if (count($offlinePlayers) == 4) {
                pushForceQuitMsg($room_no, $account);
                clearRoomDataAll($room_no);
                break;
            }
            sleep(1);
        }
    }


    /**
     * 推送失败消息
     * @param $msg
     * @return array|string
     */
    public
    function errResp($msg)
    {
        $room_data = Packet::packFormat('OK', 0, $msg);
        $room_data = Packet::packEncode($room_data, MainCmd::CMD_SYS, SubCmd::SUB_GAME_PULL_RESP);
        $this->_params['serv']->push($this->_params['userinfo']['fd'], $room_data, WEBSOCKET_OPCODE_BINARY);
    }

    /**
     * 组装房间玩家牌局数据
     * @param $room_data
     * @return array
     */

    protected function roomData($room_data)
    {
        $user_info = json_decode($room_data['uinfo'], true);
        $uidArr = [];
        foreach ($user_info as $k => $v) {
            $uidArr[] = $k;
        }
        // 查询用户信息
        $users = User::getUsers($uidArr);
        $return_data = [];
        $room_no = $room_data['room_no'];
        $colors = getRoomColors($room_no);
        foreach ($users['data'] as $ks => $vs) {
            $user_data = json_decode($room_data[$vs['account']], true);
            $cards = $user_data['card'];
//            $cards = removePGcards($cards, $user_data['peng'], $user_data['gang']);
//            sort($cards);
            $chair_id = getChairIdbyAccount($room_no, $vs['account']);
//            $is_robot = $score = is_robot($room_no, $vs['account']);
            $return_data[] = [
                'card' => $cards,
                'peng' => $user_data['peng'],
                'gang' => $user_data['gang'],
                'hu' => $user_data['hu'],
                'out_card' => $user_data['out_card'],
                'chair_id' => $user_data['chair_id'],
                'take_over' => $user_data['take_over'],
                'avatar' => $vs['avatar'],
                'nickname' => filterNickname($vs['nickname']),
                'score' => intval($user_info[$vs['account']]['total_score']),
                'que' => isset($colors[$chair_id]) ? $colors[$chair_id] : 0,
            ];
        }
        return $return_data;
    }

}
